package com.mlethe.library.recyclerview.adapter;

import android.graphics.Canvas;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.mlethe.library.recyclerview.listener.MultiTypeSupport;
import com.mlethe.library.recyclerview.listener.OnItemDragListener;
import com.mlethe.library.recyclerview.listener.OnItemSwipeListener;
import com.mlethe.library.recyclerview.viewholder.ViewHolder;

import java.util.List;

/**
 * item 滑动删除和拖拽
 * <p>
 * 使用方式:
 * ItemTouchHelper mItemHelper = new ItemTouchHelper(new ItemDragAndSwipeCallback(new BaseDraggableAdapter());
 * mItemHelper.attachToRecyclerView(recyclerView);
 *
 * @author Mlethe
 * @date 2020/9/19
 */
public abstract class BaseDraggableAdapter<T, VH extends ViewHolder> extends UniversalAdapter<T, ViewHolder> {

    private OnItemDragListener<T> mOnItemDragListener;
    private OnItemSwipeListener<T> mOnItemSwipeListener;

    protected boolean itemDragEnabled = false;
    protected boolean itemSwipeEnabled = false;

    private int startPosition = -1;
    private int endPosition = -1;

    public BaseDraggableAdapter(int layoutId) {
        super(layoutId);
    }

    public BaseDraggableAdapter(MultiTypeSupport<T> multiTypeSupport) {
        super(multiTypeSupport);
    }

    public BaseDraggableAdapter(List<T> data, int layoutId) {
        super(data, layoutId);
    }

    public BaseDraggableAdapter(List<T> data, MultiTypeSupport<T> multiTypeSupport) {
        super(data, multiTypeSupport);
    }

    /**
     * 开始拖拽
     *
     * @param viewHolder
     */
    public void onItemDragStart(@NonNull RecyclerView.ViewHolder viewHolder) {
        if (!itemDragEnabled) {
            return;
        }
        startPosition = viewHolder.getAdapterPosition();
        endPosition = startPosition;
        if (mOnItemDragListener != null) {
            int position = getViewHolderPosition(viewHolder);
            mOnItemDragListener.onItemDragStart((ViewHolder) viewHolder, getItem(position), position);
        }
    }

    /**
     * 正在拖拽
     *
     * @param source
     * @param target
     */
    public void onItemDragMoving(@NonNull RecyclerView.ViewHolder source, @NonNull RecyclerView.ViewHolder target) {
        if (!itemDragEnabled) {
            return;
        }
        int fromPosition = source.getAdapterPosition();
        int toPosition = target.getAdapterPosition();
        int headerCount = getHeaderCount();
        int from = fromPosition - headerCount;
        int to = toPosition - headerCount;

        if (inRange(from) && inRange(to)) {
            moveItem(from, to);
            startPosition = Math.min(startPosition, toPosition);
            endPosition = Math.max(endPosition, toPosition);
            notifyItemMoved(fromPosition, toPosition);
        }
        if (mOnItemDragListener != null) {
            mOnItemDragListener.onItemDragMoving((ViewHolder) source, from, (ViewHolder) target, to, getItem(to));
        }
    }

    /**
     * 拖拽结束
     *
     * @param recyclerView
     * @param viewHolder
     */
    public void onItemDragEnd(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        if (!itemDragEnabled) {
            return;
        }
        if (recyclerView.getItemDecorationCount() > 1) {
            if (startPosition != endPosition && startPosition >= 0 && endPosition >= 0) {
                notifyItemRangeChanged(startPosition, endPosition - startPosition + 1);
            }
        }
        startPosition = -1;
        endPosition = -1;
        int position = getViewHolderPosition(viewHolder);
        if (mOnItemDragListener != null) {
            mOnItemDragListener.onItemDragEnd((ViewHolder) viewHolder, getItem(position), position);
        }
    }

    /**
     * swipe 开始滑动
     *
     * @param viewHolder
     */
    public void onItemSwipeStart(@NonNull RecyclerView.ViewHolder viewHolder) {
        if (!itemSwipeEnabled) {
            return;
        }
        if (mOnItemSwipeListener != null) {
            int position = getViewHolderPosition(viewHolder);
            mOnItemSwipeListener.onItemSwipeStart((ViewHolder) viewHolder, getItem(position), position);
        }
    }

    /**
     * swipe 滑动中
     *
     * @param canvas
     * @param viewHolder
     * @param dX                X轴移动的距离
     * @param dY                Y轴移动的距离
     * @param isCurrentlyActive 如果当前被用户操作为true，反之为false
     */
    public void onItemSwiping(@NonNull Canvas canvas, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) {
        if (!itemSwipeEnabled) {
            return;
        }
        if (mOnItemSwipeListener != null) {
            mOnItemSwipeListener.onItemSwipeMoving(canvas, (ViewHolder) viewHolder, dX, dY, isCurrentlyActive);
        }
    }

    /**
     * swipe 到达滑动消失的距离
     *
     * @param viewHolder
     */
    public void onItemSwiped(@NonNull RecyclerView.ViewHolder viewHolder) {
        if (!itemSwipeEnabled) {
            return;
        }
        int position = getViewHolderPosition(viewHolder);
        if (inRange(position)) {
            notifyItemRemove(position);
            if (mOnItemSwipeListener != null) {
                mOnItemSwipeListener.onItemSwiped((ViewHolder) viewHolder, getItem(position), position);
            }
        }
    }

    /**
     * @param viewHolder
     */
    public void onItemSwipeClear(@NonNull RecyclerView.ViewHolder viewHolder) {
        if (mOnItemSwipeListener != null && itemSwipeEnabled) {
            int position = getViewHolderPosition(viewHolder);
            mOnItemSwipeListener.onItemSwipeClear((ViewHolder) viewHolder, getItem(position), position);
        }
    }

    public boolean isItemDragEnabled() {
        return itemDragEnabled;
    }

    public boolean isItemSwipeEnabled() {
        return itemSwipeEnabled;
    }

    /**
     * Enable drag items.
     */
    public BaseDraggableAdapter<T, VH> enableDragItem() {
        itemDragEnabled = true;
        return this;
    }

    /**
     * Disable drag items.
     */
    public BaseDraggableAdapter<T, VH> disableDragItem() {
        itemDragEnabled = false;
        return this;
    }

    /**
     * Enable swipe items.
     */
    public BaseDraggableAdapter<T, VH> enableSwipeItem() {
        itemSwipeEnabled = true;
        return this;
    }

    /**
     * Disable swipe items.
     */
    public BaseDraggableAdapter<T, VH> disableSwipeItem() {
        itemSwipeEnabled = false;
        return this;
    }

    /**
     * 设置拖拽监听
     *
     * @param onItemDragListener
     * @return
     */
    public BaseDraggableAdapter<T, VH> setOnItemDragListener(OnItemDragListener<T> onItemDragListener) {
        this.mOnItemDragListener = onItemDragListener;
        return this;
    }

    /**
     * 设置滑动删除监听
     *
     * @param onItemSwipeListener
     * @return
     */
    public BaseDraggableAdapter<T, VH> setOnItemSwipeListener(OnItemSwipeListener<T> onItemSwipeListener) {
        this.mOnItemSwipeListener = onItemSwipeListener;
        return this;
    }
}
